package com.example.demo.service;

import com.example.demo.account.AccountInfo;
import com.example.demo.entity.AccountEntity;
import com.example.demo.entity.CopyrightEntity;
import com.example.demo.entity.CopyrightTransferEntity;
import com.example.demo.model.CopyrightInfo;
import com.example.demo.model.CopyrightTransferInfo;
import com.example.demo.repository.CopyrightRepository;
import com.example.demo.repository.CopyrightTransferRepository;
import lombok.extern.slf4j.Slf4j;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor;
import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory;
import org.fisco.bcos.sdk.transaction.model.dto.CallResponse;
import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 版权服务接口，提供版权创建、转移和查询功能
 */
public interface CopyrightService {

    /**
     * 版权转让事件监听器接口
     */
    @FunctionalInterface
    interface TransactionReceiptListener {
        void onReceipt(TransactionReceipt receipt);
    }
    
    /**
     * 添加交易回执监听器
     * @param listener 监听器
     */
    void addTransactionReceiptListener(TransactionReceiptListener listener);
    
    /**
     * 移除交易回执监听器
     */
    void removeTransactionReceiptListener();
    
    /**
     * 转移版权
     * @param copyrightId 版权ID
     * @param fromAddress 源地址
     * @param toAddress   目标地址
     * @return CopyrightInfo 版权信息
     */
    CopyrightInfo transferCopyright(String copyrightId, String fromAddress, String toAddress);
    
    /**
     * 获取版权信息
     * @param copyrightId 版权ID
     * @return 版权信息
     */
    CopyrightInfo getCopyright(BigInteger copyrightId);
    
    /**
     * 获取所有者的版权ID列表
     * @param address 所有者地址
     * @return 版权ID列表
     */
    List<BigInteger> getCopyrightsByOwner(String address);
    
    /**
     * 获取客户端
     * @return 区块链客户端
     */
    Client getClient();
    
    /**
     * 从数据库获取所有者的版权列表
     * @param ownerAddress 所有者地址
     * @return 版权信息列表
     */
    List<CopyrightInfo> getCopyrightsByOwnerFromDB(String ownerAddress);
    
    /**
     * 从数据库获取指定哈希的版权列表
     * @param imageHash 图片哈希
     * @return 版权信息列表
     */
    List<CopyrightInfo> getCopyrightsByImageHashFromDB(String imageHash);
    
    /**
     * 从数据库获取所有者的有效版权列表
     * @param ownerAddress 所有者地址
     * @return 有效版权信息列表
     */
    List<CopyrightInfo> getValidCopyrightsByOwnerFromDB(String ownerAddress);
    
    /**
     * 将实体转换为信息对象
     * @param entity 版权实体
     * @return 版权信息
     */
    CopyrightInfo convertEntityToInfo(CopyrightEntity entity);
    
    /**
     * 同步版权数据
     */
    void syncCopyrightData();
    
    /**
     * 获取所有者的所有版权
     * @param ownerAddress 所有者地址
     * @return 版权信息列表
     */
    List<CopyrightInfo> getAllCopyrightsByOwner(String ownerAddress);
    
    /**
     * 获取所有者的有效版权
     * @param ownerAddress 所有者地址
     * @return 有效版权信息列表
     */
    List<CopyrightInfo> getValidCopyrightsByOwner(String ownerAddress);
    
    /**
     * 获取版权的转让历史
     * @param copyrightId 版权ID
     * @return 转让历史记录
     */
    List<CopyrightTransferEntity> getTransferHistory(BigInteger copyrightId);
    
    /**
     * 获取从指定地址发起的转让记录
     * @param address 发起方地址
     * @return 转让记录
     */
    List<CopyrightTransferEntity> getTransfersByFromAddress(String address);
    
    /**
     * 获取到指定地址的转让记录
     * @param address 接收方地址
     * @return 转让记录
     */
    List<CopyrightTransferEntity> getTransfersByToAddress(String address);
    
    /**
     * 从数据库获取版权信息
     * @param id 版权ID
     * @return 版权信息
     */
    CopyrightInfo getCopyrightFromDB(BigInteger id);
    
    /**
     * 创建版权存证
     * @param address 所有者地址
     * @param imageHash 图片哈希
     * @param file 图片文件
     * @param imageName 图片名称
     * @param modelName 模型名称
     * @param prompt 提示词
     * @return 版权ID
     */
    BigInteger createCertificate(String address, String imageHash, MultipartFile file, 
                                String imageName, String modelName, String prompt);
    
    /**
     * 获取指定哈希的有效版权
     * @param imageHash 图片哈希
     * @return 版权信息列表
     */
    List<CopyrightInfo> getValidCopyrightsByHash(String imageHash);
    
    /**
     * 创建存证并获取信息
     * @param address 所有者地址
     * @param imageName 图片名称
     * @param modelName 模型名称
     * @param prompt 提示词
     * @param file 图片文件
     * @return 版权信息
     */
    CopyrightInfo createCertificateAndGetInfo(String address, String imageName, String modelName, String prompt, MultipartFile file) throws Exception;
    
    /**
     * 获取版权转让历史信息
     * @param copyrightId 版权ID
     * @return 转让历史信息
     */
    List<CopyrightTransferInfo> getTransferHistoryInfo(BigInteger copyrightId);
    
    /**
     * 获取用户发起的转让记录信息
     * @param address 用户地址
     * @return 转让记录信息
     */
    List<CopyrightTransferInfo> getTransfersFromUserInfo(String address);
    
    /**
     * 获取用户接收的转让记录信息
     * @param address 用户地址
     * @return 转让记录信息
     */
    List<CopyrightTransferInfo> getTransfersToUserInfo(String address);
    
    /**
     * 验证图片版权
     * @param file 图片文件
     * @return 验证结果
     */
    Map<String, Object> verifyImageCopyright(MultipartFile file) throws Exception;
    
    /**
     * 通过哈希验证版权
     * @param imageHash 图片哈希
     * @return 验证结果
     */
    Map<String, Object> verifyByHash(String imageHash);

    /**
     * 从区块链获取指定地址拥有的所有版权的详细信息
     * @param address 账户地址
     * @return 版权信息列表
     */
    List<CopyrightInfo> getAllCopyrightsFromChain(String address);
} 